package com.track.utils;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Objects;

/**
 * 远程脚本执行器
 *
 * @author springer
 */
@Slf4j
public class RemoteShellExecutor {

    private Connection connection;

    private final String ip;

    private final String user;

    private final String password;

    private final String charset = Charset.defaultCharset().toString();

    private final boolean setupMutualTrust;

    public RemoteShellExecutor(String ip, String user, String password, boolean setupMutualTrust) {
        this.ip = ip;
        this.user = user;
        this.password = password;
        this.setupMutualTrust = setupMutualTrust;
    }

    @SneakyThrows
    public boolean connect() {
        log.debug("Try connect {}.", ip);
        connection = new Connection(ip);
        connection.connect();
        log.debug("Try mutual trust login.");
        boolean isConnect = connection.authenticateWithNone(user);
        if (!isConnect) {
            log.debug("Connect error.");
            log.debug("Try login with user name and password.");
            isConnect = connection.authenticateWithPassword(user, password);
            if (!isConnect) {
                log.debug("Connect error.");
            }
        }
        return isConnect;
    }


    @SneakyThrows
    public String exec(String cmd) {
        if (!connect()) {
            return StrUtil.EMPTY;
        }

        if (setupMutualTrust) {

        }
        StringBuilder result;
        InputStream stdout = null;
        InputStream stderr = null;
        Session session = null;
        try {
            result = new StringBuilder();
            session = connection.openSession();

            log.debug("Exec shell '{}'", cmd);
            session.execCommand(cmd, charset);

            stdout = new StreamGobbler(session.getStdout());
            stderr = new StreamGobbler(session.getStderr());
            BufferedReader out = new BufferedReader(new InputStreamReader(stdout, charset));
            BufferedReader outErr = new BufferedReader(new InputStreamReader(stderr, charset));
            log.debug("Read ssh result.");
            while(true){
                String line = out.readLine();
                if(line==null){
                    break;
                }
                result.append(line).append("<br/>");
                log.debug(line);
            }
            while(true){
                String line = outErr.readLine();
                if(line==null){
                    break;
                }
                result.append(line).append("<br/>");
                log.debug(line);
            }

        } finally {
            if (Objects.nonNull(session)) {
                session.close();
            }
            if (Objects.nonNull(connection)) {
                connection.close();
            }
            IOUtils.close(stdout);
            IOUtils.close(stderr);
        }
        return result.toString();
    }

    public static void main(String[] args) {
        RemoteShellExecutor executor = new RemoteShellExecutor("192.168.31.229", "root", "szzzkvm01", true);
        executor.exec("supervisorctl stop partner-20020");
    }

}
